package com.easepal.socketiolib;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.IBinder;
import android.os.PowerManager;
import androidx.annotation.Nullable;

import com.easepal.socketiolib.log.LogUtil;

/**
 * 作者: bright.lin@medisana.net.cn
 * 时间: 2018/12/6
 * 标题: WebSocket服务
 * 描述: 实现WebSocket客户端功能的本地服务
 * 修改: 由 bright.lin@medisana.net.cn 修改于 2018/12/6
 */
public class WebSocketService extends Service {
    private static final String TAG = WebSocketService.class.getName();

    // 手机网络连接状态接收器
    private NetworkConnectionIntentReceiver networkConnectionMonitor;
    // WebSocket服务Binder
    private WebSocketServiceBinder webSocketServiceBinder;
    // Socket连接对象
    private SocketConnection connection;

    /**
     * 无参构造器
     */
    public WebSocketService() {
        super();
    }

    /**
     * 获取Socket连接对象
     *
     * @return Socket连接对象
     */
    SocketConnection getConnection() {
        if (null == connection) {
            connection = new SocketConnection();
        }
        return connection;
    }

    /**
     * 连接
     *
     * @param url   服务器地址
     * @param token 异步标签
     */
    void connect(String url, String token) {
        if (null != connection) {
            connection.connect(url, token);
        } else {
            throw new IllegalArgumentException("Connection is null");
        }
    }

    /**
     * 获取连接状态
     *
     * @return 连接状态
     */
    boolean isConnected() {
        if (null != connection) {
            return connection.isConnected();
        } else {
            return false;
        }
    }

    /**
     * 发送消息
     *
     * @param text 消息
     */
    void sent(String text) {
        if (null != connection) {
            connection.sent(text);
        } else {
            throw new IllegalArgumentException("Connection is null");
        }
    }

    /**
     * 关闭连接
     */
    void close() {
        if (null != connection) {
            connection.close(false);
        }
    }

    /*Service父类方法*/

    /**
     * @see Service#onCreate()
     */
    @Override
    public void onCreate() {
        super.onCreate();

        webSocketServiceBinder = new WebSocketServiceBinder(this);
    }

    /**
     * @see Service#onDestroy()
     */
    @Override
    public void onDestroy() {

        if (null != connection) {
            connection.close(false);
        }

        if (null != webSocketServiceBinder) {
            webSocketServiceBinder = null;
        }

        unregisterBroadcastReceivers();

        super.onDestroy();
    }

    /**
     * @see Service#onBind(Intent)
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return webSocketServiceBinder;
    }

    /**
     * @see Service#onStartCommand(Intent, int, int)
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 注册广播接收
        registerBroadcastReceivers();

        return START_STICKY;
    }
    /*Service父类方法*/

    /**
     * 注册广播接收
     */
    private void registerBroadcastReceivers() {
        if (networkConnectionMonitor == null) {
            networkConnectionMonitor = new NetworkConnectionIntentReceiver();
            registerReceiver(networkConnectionMonitor, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        }
    }

    /**
     * 注销广播接收
     */
    private void unregisterBroadcastReceivers() {
        if (networkConnectionMonitor != null) {
            unregisterReceiver(networkConnectionMonitor);
            networkConnectionMonitor = null;
        }
    }

    /**
     * 当手机网络状况改变时接收广播
     */
    private class NetworkConnectionIntentReceiver extends BroadcastReceiver {

        @Override
        @SuppressLint("Wakelock")
        public void onReceive(Context context, Intent intent) {
            // we protect against the phone switching off
            // by requesting a wake lock - we request the minimum possible wake
            // lock - just enough to keep the CPU running until we've finished
            PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            if (pm != null) {
                PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WebSocketService.class.getName());
                wl.acquire(10000);
                if (null != connection) {
                    if (isOnline()) {
                        LogUtil.d(TAG, "isOnline");
                        connection.notifyReconnect();
                    } else {
                        LogUtil.d(TAG, "isOffline");
                        connection.close(false);
                    }
                }

                wl.release();
            }
        }
    }

    /**
     * 通过系统服务获取当前手机网络状况
     *
     * @return 当手机网络可用时返回true
     */
    boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        if (cm != null) {
            NetworkInfo networkInfo = cm.getActiveNetworkInfo();
            //noinspection RedundantIfStatement
            if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()) {
                return true;
            }
        }
        return false;
    }
}
